﻿#pragma once
#ifndef BTOSG_H
#define BTOSG_H

#pragma execution_character_set("utf-8")
#include <osgDB/ReadFile>
#include <osg/MatrixTransform>
#include <osg/PositionAttitudeTransform>
#include <osgGA/TrackballManipulator>
#include <osg/ShapeDrawable>
#include <osg/Plane>
#include <osg/LightSource>
#include <osg/Material>
#include<qdebug.h>
#include <btBulletDynamicsCommon.h>
#include "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h"
#include <forward_list>
#ifndef max
#define max(a, b) (((a) > (b)) ? (a) : (b))
#endif
#include <QDebug>
#include<string>

#include <osg/Texture2D>

//标记：我不知道为什么要用16进制,现在这里标记一下
const int ReceivesShadowTraversalMask = 0x1;
const int CastsShadowTraversalMask = 0x2;

inline int btosgPrint(char const *name, const int v) {
    return printf("%s: %d\n", name, v);
}
inline int btosgPrint(char const *name, const float v) {
    return printf("%s: %f\n", name, v);
}

inline int btosgPrint(char const *name, const btVector3&  vec) {
    return printf("%s: %f %f %f\n", name, vec[0], vec[1], vec[2]);
}




//! btosgVec3 can be used to represent 3D points and vectors.
/*! Can be used as a btVector3 or an osg::Vec3.
 *  Implemented as derived from osg::Vec3 with aditional constructor and convertor from and to btVector3.
 */
//简单来说，这个就是一个用于实现osg的vec和btvec相互转化的类
//这里不是相互转化，这是向着osg的转化
class btosgVec3 : public osg::Vec3 {
public:
    /**@brief Default constructor
     */
    btosgVec3() : osg::Vec3() {}

    /**@brief Constructor from 3 scalars
     * @param x X value
     * @param y Y value
     * @param z Z value
     */
    btosgVec3(double x, double y, double z) : osg::Vec3(x,y,z) {}

    //! Constructor from osg::Vec3f
    /*! @param v osg::Vec3 object
     */
    btosgVec3(osg::Vec3f v) : osg::Vec3(v) {}

    //! Constructor from osg::Vec3d
    /*! @param v osg::Vec3 object
     */
    btosgVec3(osg::Vec3d v) : osg::Vec3(v) {}

    //! Constructor from btVector3
    /*! @param v btVector3 object
     */
//    转化为osg的向量
    btosgVec3(btVector3  v) : osg::Vec3(v[0],v[1],v[2]) {}

    //! Converter operator to Bullet Vector
    /*! Returns vector as a btVector3 object
     */
    //这里是实现对子弹向量的隐式转换
    operator btVector3() const {
        return btVector3(x(), y(), z());
    }
};



//! btosgQuat represents a Quaternion.
/*! Can be used as a btQuaternion or an osg::Quat.
 *  Implemented as derived from osg::Quar with aditional constructor and convertor from and to btQuaternion.
 */
//和上面的操作是一样的
class btosgQuat : public osg::Quat {
public:
    btosgQuat() : osg::Quat() {}
    /**@brief Constructor from 4 scalars
     * @param x X value
     * @param y Y value
     * @param z Z value
     * @param w W value
     */
    btosgQuat(double x, double y, double z, double w) : osg::Quat(x,y,z,w) {}

    //! Constructor from base class osg::Quat
    /*! @param q osg::Quat object
     */
    btosgQuat(osg::Quat  q) : osg::Quat(q) {}

    //! Constructor from Bullet quaternion btQuaternion
    /*! @param q btQuaternion object
     */
    btosgQuat(btQuaternion  q) : osg::Quat(q[0],q[1],q[2],q[3]) {}

    //! Constructor from btosgVec3 and scalar
    /*! @param axis btosgVec3 rotation axis
     *  @param ang  double rotation angle
     */
    //提供旋转轴和旋转角度
    btosgQuat(btosgVec3 axis, double ang) : osg::Quat(ang, axis) {}

    //! Convertor operator to Bullet quaternion
    /*! Returns quaternion as a btQuaternion object
     */
    //这里是进行隐式转换，这样的话可以相互转换赋值
    operator btQuaternion() const {
        return btQuaternion(x(), y(), z(), w());
    }

    //! Converter to Euler angles
    /*! Returns a btoasgVec3 object with HPR Euler angles
     */
    //使用HPR的欧拉角计算方式
    btosgVec3 toEuler();
};

//!  Main btosg object base class.
/*!  Integrates a physical object (btRigidBody), a collision shape (btCollisionShape)
 *   and a graphical object (osg::PositionAttitudeTransform).
 *   Most object classes derive directly from btosgObject class.
 */
class btosgObject{
public:
    //图形
    osg::ref_ptr<osg::PositionAttitudeTransform> model;
    //刚体
    btRigidBody *body;
    char *name;
    btTransform init_state;
    btCollisionShape *shape;
    float mass;

    btosgObject(){
        model=NULL;
        this->body=NULL;
        this->init_state=btTransform();
        this->shape=NULL;
        this->mass=0;
        this->name=NULL;

    }
    virtual ~btosgObject() {
        if (body) {
            delete body->getMotionState();
            delete body;
            body = NULL;
        }
        if( model ) {
            //model->unref();
            //model = NULL;
        }
        if (shape) {
            delete shape;
            shape = NULL;
        }
        if (name) {
            free(name);
            name = NULL;
        }
    }

    void print();
    /**
     * @brief setName
     * 他这里是深拷贝，和原来的是两个字符串
     * @param n
     */
    void setName(char const *n) {
        /// Sets the object's name.
        name = strdup(n);
    }

    //设置质量的时候同时也把他的惯性计算出来并保存
    void setMass(double m) {
        mass=m;
        bool isDynamic =(mass !=0.f);
        btVector3 localInertia(0,0,0);
        if(isDynamic && this->shape){
            shape->calculateLocalInertia(mass,localInertia);
        }
        if(this->body){
            body->setMassProps(m,localInertia);
        }

    }

    //通过刚体或者model获取
    btosgVec3 getPosition(){
        if(this->body){
            btTransform wTrans;
            this->body->getMotionState()->getWorldTransform(wTrans);
            return  wTrans.getOrigin();
        }
        if(this->model){
            return model->getPosition();
        }
        return btosgVec3(0.,0.,0.);

    }


    //通过刚体或者model获取
   btosgQuat getRotation() {
       if(this->body){
           btTransform wTrans;
           this->body->getMotionState()->getWorldTransform(wTrans);
           return wTrans.getRotation();
       }
       if(this->model){
           return model->getAttitude();
       }
       return btosgQuat(0.,0.,0.,1.);
   }
   //先获取四元函数，然后通过固定的公式把四元函数转化成Eule
   btosgVec3 getEuler() {
       /// Returns object's attitude as HPR Euler angles.
       btosgQuat qt = getRotation();
       return qt.toEuler();
   }


   //这里都重载了
   //重点：这里我不太清楚
   //三维的
   void setTransform(const btTransform &wTrans){
       /// Sets position and orientation of object using btTransform
       if(this->body){
           body->setWorldTransform(wTrans);
           body->getMotionState()->setWorldTransform(wTrans);
           body->clearForces();
           body->setAngularVelocity(btVector3(0,0,0));
           body->setLinearVelocity(btVector3(0,0,0));
       }


   }

   //这里只是设置模型的姿态 重点
   void setPosition(const btosgVec3 &p){
       if (model) {
//           model->setPosition(p*10);
           model->setPosition(p);
       }
//       if (body) {
//           btTransform wTrans;
//           body->getMotionState()->getWorldTransform(wTrans);
//           wTrans.setOrigin(p);
//           setTransform(wTrans);
//       }
   }

   void setPosition(float x, float y, float z) {
       /// Sets objects position.
       setPosition(btosgVec3(x,y,z));
   }

   /**
    * @brief setRotation
    * 旋转这玩意主要就是从刚体中把模型取出来，然后对他进行操作也是需要更新世界matrix，和运动状态matrix，然后清除受力情况
    * 然后这里在清除线速度和角速度，
    * 然后我这里也需要去设置模型，这里就修改模型的rotation就可以了，模型的rotation是setAttribute
    *
    * @param q
    */
   void setRotation(btosgQuat q){
       if(this->body){
           btTransform wTrans;
           body->getMotionState()->getWorldTransform(wTrans);
           wTrans.setRotation(q);
           body->setWorldTransform(wTrans);
           body->getMotionState()->setWorldTransform(wTrans);
           body->clearForces();
           body->setLinearVelocity(btVector3(0,0,0));
           body->setAngularVelocity(btVector3(0,0,0));

       }
       if (model) {
           model->setAttitude(q);
       }
   }

    void setTexture(char const *fname);


    void setMaterial(osg::ref_ptr<osg::Material> mat) {
        /// Sets the material properties for the object.
        model->getOrCreateStateSet()->setAttributeAndModes(mat, osg::StateAttribute::ON);
    }

    /**
     * @brief logPosition
     * 重要  在控制台打印输出日志，可以修改到文件里面
     */
    void logPosition() {
        /// Outputs object's position.
        btosgVec3 pos = getPosition();
        if ( name )
            std::cout << "Object " << name << " position " << pos[0] << " " << pos[1] << " " << pos[2] << std::endl;
        else
            std::cout << "Object _NO_NAME_ position " << pos[0] << " " << pos[1] << " " << pos[2] << std::endl;
    }

    /**
     * @brief update
     * 这里就是从运动状态里面取出运动举证，然后去设置图形的位置和旋转
     */
    virtual void update() {
        /// Objects's update callback.
        /// This function is called automatically from World::stepSimulation() for each registered object.
        /// Positions graphical object from its physhical state.

        if(this->body){
            btTransform wTrans;
            body->getMotionState()->getWorldTransform(wTrans);
            if(model){
                model->setAttitude(btosgQuat(wTrans.getRotation()));
                model->setPosition(btosgVec3(wTrans.getOrigin()));
            }
        }


    }

    //初始化
    void reset();

    //这里是设置初始化的那个举证，并不是u改变body的值 重点
    void setInitState() {
        /// Stores current state as init state.
        /// Init state is aplied by reset()
        if (body) body->getMotionState()->getWorldTransform(init_state);
    }
    void setInitState(btTransform iState) {
        /// Stores iState as init state.
        /// Init state is applied by reset()
        init_state = iState;
    }

    void createRigidBody();

    void loadObjectModel(char const *fname);
    //这个函数，多半是用来把它重置到原点用的，然后随意取的一个名字
    void test(const btosgVec3 &p)
    {
        if (body) {
            btTransform wTrans;
            body->getMotionState()->getWorldTransform(wTrans);
            wTrans.setOrigin(p);
            wTrans.setRotation(btQuaternion(0,0,0,1));
            setTransform(wTrans);
        }
        else{
            if(model) {
                model->setPosition(p);
            }
        }
    }






};












//! Physical and visual world.
/*! Integrates a btDynamicsWorld and an osg::Group.
 *  Provides automated updating of graphical objects from related
 *  physical simulated bodies.
 */
class btosgWorld{
private:
    unsigned long steps;
    unsigned long nObjs;
    btDbvtBroadphase *broadphase;
    btDefaultCollisionConfiguration *collisionConfiguration;
    btCollisionDispatcher *dispatcher;
    btSequentialImpulseConstraintSolver *solver;

public:
    //body在这里面
    btDynamicsWorld *dynamic;
    //这个model都在这里面
    osg::ref_ptr<osg::Group> scene;
    //这个是场景里面的物品 刚体和形状都有
    std::forward_list<btosgObject *> objects;
    osg::ref_ptr<osg::Group> root = new osg::Group();

    btosgWorld(){
        // Create dynamic world
//        一共四个参数
        //碰撞的配置和碰撞分发器
        collisionConfiguration=new btDefaultCollisionConfiguration();
        dispatcher=new btCollisionDispatcher(collisionConfiguration);
//        (dynamic Bounding Volume Tree)
        broadphase=new btDbvtBroadphase;
        this->solver=new btSequentialImpulseConstraintSolver;

        this->dynamic=new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,this->collisionConfiguration);

        dynamic->setGravity(btosgVec3(0., 0., -9.8));

        this->scene=new osg::Group;


        //暂时不知道有什么用
        steps = 0L;
        nObjs = 0L;

// 创建默认的碰撞配置，用于初始化碰撞处理系统的各种参数和设置
collisionConfiguration = new btDefaultCollisionConfiguration();

// 创建碰撞调度器，用于决定如何处理物体间的碰撞，基于之前创建的碰撞配置
dispatcher = new btCollisionDispatcher(collisionConfiguration);

// 创建宽相位碰撞检测系统（使用动态包围体树，Dynamic Bounding Volume Tree），用于快速识别可能发生碰撞的物体对
broadphase = new btDbvtBroadphase();

// 创建约束求解器，用于处理物体间的约束和碰撞后的物理响应
this->solver = new btSequentialImpulseConstraintSolver();

// 创建动力学世界，它是物理模拟的核心，负责整合上述组件来模拟物理环境中的动力学行为
this->dynamic = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, this->collisionConfiguration);




    }
    ~btosgWorld();

    //设置运行时候的帧率，让他们运动
    void stepSimulation(btScalar timeStep, int maxSubSteps);
    //添加进去一个物体，同时具有刚体和可视化的模型
    void addObject(class btosgObject *obj);
//        删除一个物体，从动态世界中删除刚体，从scene中删除可视化的模型
    void removeObject(class btosgObject *obj);
//        列出这些可视化的物体
    void listObjects();
//        这里是删除掉所有可视化的物体
    int  deleteAllObjects();
    //复位操作
    void reset();





};


/// Infinite plane
//plane既是平面也是飞机的意思，这里就是平面
class btosgPlane : public btosgObject{
    // Physical infinit, axis oriented plane.
    // Viewable as a finit, axis oriented, small depth box.
private:
    float dx,dy,dz;
public:
    btosgPlane()  :  btosgPlane(10., 10., 0.) {
        /// Constructs a physical infinite plane, viewable as low thickness finite box.
        /// Viewable box has dimensions 10,10,0.
        /// plane is created facing Z axis.
    }

    btosgPlane( btosgVec3 v ) : btosgPlane( v[0], v[1], v[2] ) {
        /// Constructs a physical infinite plane, viewable as low thickness finite box.
        /// Viewable box has dimensions v.x,v.y,v.z.
        /// Minimum dimension selects physical plane orientatiton.
        /// Plane is created as axis oriented.
    }
    btosgPlane(float dx, float dy, float dz)  {
      //  /// Constructs a physical infinite plane, viewable as low thickness finite box.
      //  /// Viewable box has dimensions dx,dy,dz.
       // /// Minimum dimension selects physical plane orientation.
       // /// Plane is created as axis oriented.
        dx=max(dx,0.001);
        dy=max(dy,0.001);
        dz=max(dz,0.001);
        osg::Geode *geo=new osg::Geode;
        if(geo){
            osg::Shape *sp=new osg::Box(osg::Vec3(0.,0.,0.),dx,dy,dz);
            if(sp){
                osg::ShapeDrawable *sd=new osg::ShapeDrawable(sp);
                if(sd){
                    geo->addDrawable(sd);
                }else fprintf(stderr,"Error creating osg::Shape\n");
            } else fprintf(stderr,"Error creating osg::Shape\n");
        } else fprintf(stderr,"Error creating Geode\n");

        if ( !model )	model = new osg::PositionAttitudeTransform;
        model->addChild(geo);
        //这个是什么意思
        model->setNodeMask(ReceivesShadowTraversalMask);
        mass = 0;
        btVector3 norm(0.,0.,1);
        if ( dx<dy && dx<dz ) 	   norm = btVector3(1.,0.,0.);
        else if ( dy<dx && dy<dz ) norm = btVector3(0.,1.,0.);
        shape=new btStaticPlaneShape(norm,0);
        if(!shape){
            fprintf(stderr,"Error creating btShape\n");

        }
        createRigidBody();

    }

    void createRigidBody() {
         /// Creates a Rigid Body
        btDefaultMotionState* mState = new
            btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0.,0.,0.)));
        btVector3 inertia(0,0,0);
        //shape->calculateLocalInertia(mass,inertia);
        btRigidBody::btRigidBodyConstructionInfo cInfo(mass,mState,shape,inertia);
        cInfo.m_restitution=0.9f;
        cInfo.m_friction=0.9f;
        body=new btRigidBody(cInfo);
        if ( !body ) fprintf(stderr,"Error creating btBody\n");
    }
    ~btosgPlane() {

    }


};

//class btosgSun : public btosgObject{
//    const std::string sun_MODEL_PATH="F:\applications\3dsmax2021\workHome\export\sun\sun0317.osg";


//};

//file:///F:/applications/3dsmax2021/workHome/export/02bullet/ground.ive

class btosgMoonGround : public btosgObject{
    // Physical infinit, axis oriented plane.
    // Viewable as a finit, axis oriented, small depth box.
private:
    float dx,dy,dz;
public:


public:
//    const std::string MYMOONGROUND_MODEL_PATH="F:/applications/3dsmax2021/workHome/export/02bullet/ground6_big.ive";
//    const std::string MYMOONGROUND_PATH="F:/applications/3dsmax2021/workHome/export/02bullet/ground6.ive";
//    const std::string MYMOONGROUND_MODEL_PATH="F:/applications/3dsmax2021/workHome/export/02bullet/20240303ground6.ive";
     const std::string MYMOONGROUND_MODEL_PATH="F:/applications/3dsmax2021/workHome/export/02bullet/20240307ground6.ive";
     const std::string MYMOONGROUND_PATH="F:/applications/3dsmax2021/workHome/export/02bullet/20240307ground6.ive";

     const std::string EARTH_IMAGE_PATH="F:/applications/3dsmax2021/workHome/export/sun/earthTexture.jpg";
     const std::string SUN_IMAGE_PATH="F:/applications/3dsmax2021/workHome/export/sun/2k_sun.jpg";
     const std::string MOON_IMAGE_PATH="F:/applications/3dsmax2021/workHome/export/sun/moon05.jpeg";
     osg::ref_ptr<osg::PositionAttitudeTransform> sunmodel;


     void createEarth(){
         int earthPosx=-1000;
         int earthPosy=10000;
         int earthPosz=500;
         osg::Geode *geo=new osg::Geode;


         osg::ref_ptr<osg::Shape> shapeSun=new osg::Sphere(osg::Vec3(earthPosx,earthPosy,earthPosz),500);
         osg::ref_ptr<osg::ShapeDrawable> shapeDrawable=new osg::ShapeDrawable(shapeSun);

         //添加纹理
         osg::ref_ptr<osg::Image> image=osgDB::readImageFile(EARTH_IMAGE_PATH);
         osg::ref_ptr<osg::Texture2D> texture=new osg::Texture2D;
         texture->setImage(image);

         //获取球体的状态集并应用
         osg::ref_ptr<osg::StateSet> ss=shapeDrawable->getOrCreateStateSet();
         ss->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
         //关闭外界光对其照射的效果
         ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
         //然后设置材质，让他可以自己发光
         osg::ref_ptr<osg::Material> material=new osg::Material;
         material->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4(1.0, 1.0, 0.0, 1.0));
         ss->setAttributeAndModes(material,osg::StateAttribute::ON);







         geo->addDrawable(shapeDrawable);

         model->addChild(geo);

     }

     void createSun(){

         int sunPosx=10000;
         int sunPosy=40000;
         int sunPosz=5000;
         osg::Geode *geo=new osg::Geode;
//         std::cout<<"111"<<std::endl;
//         osg::Node *sun=osgDB::readNodeFile(SUN_MODEL_PATH);

//        std::cout<<"222"<<std::endl;
//         osg::Geometry *geometry=findGeometryNode(sun);
//         std::cout<<"333"<<std::endl;
////         geo->addChild(geometry);
//         model->addChild(geometry);
//         std::cout<<"444"<<std::endl;
//         osg::ref_ptr<osg::Shape> cy=new osg::Cylinder(osg::Vec3(0.,0.,0.),dx,dy);
         osg::ref_ptr<osg::Shape> shapeSun=new osg::Sphere(osg::Vec3(sunPosx,sunPosy,sunPosz),400);
         osg::ref_ptr<osg::ShapeDrawable> shapeDrawable=new osg::ShapeDrawable(shapeSun);

         //添加纹理
         osg::ref_ptr<osg::Image> image=osgDB::readImageFile(SUN_IMAGE_PATH);
         osg::ref_ptr<osg::Texture2D> texture=new osg::Texture2D;
         texture->setImage(image);

         //获取球体的状态集并应用
         osg::ref_ptr<osg::StateSet> ss=shapeDrawable->getOrCreateStateSet();
         ss->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
         //关闭外界光对其照射的效果
         ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
         //然后设置材质，让他可以自己发光
         osg::ref_ptr<osg::Material> material=new osg::Material;
         material->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4(1.0, 1.0, 0.0, 1.0));
         ss->setAttributeAndModes(material,osg::StateAttribute::ON);
         osg::ref_ptr<osg::Light> sunLight = new osg::Light();
         sunLight->setLightNum(0);
         sunLight->setPosition(osg::Vec4(sunPosx, sunPosy, sunPosz, 0.0)); // 定向光，方向为 -Z
         sunLight->setDirection(osg::Vec3(0.0, 0.0, -1.0));
         sunLight->setDiffuse(osg::Vec4(1.0, 1.0, 1.0, 1.0)); // 白色光
         sunLight->setSpecular(osg::Vec4(1.0, 1.0, 1.0, 1.0));
         sunLight->setLinearAttenuation(0.0); // 减少线性衰减
         sunLight->setQuadraticAttenuation(0.0); // 减少二次衰减
         osg::ref_ptr<osg::LightSource> sunLightSource = new osg::LightSource();
         sunLightSource->setLight(sunLight);








         geo->addDrawable(shapeDrawable);

         model->addChild(geo);
         model->addChild(sunLightSource );



     }

    btosgMoonGround()  :  btosgMoonGround(10., 10., 0.) {
        /// Constructs a physical infinite plane, viewable as low thickness finite box.
        /// Viewable box has dimensions 10,10,0.
        /// plane is created facing Z axis.
    }

    btosgMoonGround( btosgVec3 v ) : btosgMoonGround( v[0], v[1], v[2] ) {
        /// Constructs a physical infinite plane, viewable as low thickness finite box.
        /// Viewable box has dimensions v.x,v.y,v.z.
        /// Minimum dimension selects physical plane orientatiton.
        /// Plane is created as axis oriented.
    }


//三角网格
    btosgMoonGround(float dx, float dy, float dz)  {

      //  /// Constructs a physical infinite plane, viewable as low thickness finite box.
      //  /// Viewable box has dimensions dx,dy,dz.
       // /// Minimum dimension selects physical plane orientation.
       // /// Plane is created as axis oriented.
        dx=max(dx,0.001);
        dy=max(dy,0.001);
        dz=max(dz,0.001);
//        osg::Geode *geo=new osg::Geode;
//        if(geo){
//            osg::Shape *sp=new osg::Box(osg::Vec3(0.,0.,0.),dx,dy,dz);
//            if(sp){
//                osg::ShapeDrawable *sd=new osg::ShapeDrawable(sp);
//                if(sd){
//                    geo->addDrawable(sd);
//                }else fprintf(stderr,"Error creating osg::Shape\n");
//            } else fprintf(stderr,"Error creating osg::Shape\n");
//        } else fprintf(stderr,"Error creating Geode\n");
        osg::Geode *geo=new osg::Geode;
        osg::Node *ground=osgDB::readNodeFile(MYMOONGROUND_PATH);
        osg::Node *groundModel=osgDB::readNodeFile(MYMOONGROUND_MODEL_PATH);

        osg::Geometry *geometry=findGeometryNode(ground);
        osg::Geometry *geometryModel=findGeometryNode(groundModel);
//        //添加纹理


        geo->addChild(geometryModel);





        if ( !model )	model = new osg::PositionAttitudeTransform;
        model->addChild(geo);
        //这个是什么意思
        model->setNodeMask(ReceivesShadowTraversalMask);
        mass = 0;
        btVector3 norm(0.,0.,1);
        if ( dx<dy && dx<dz ) 	   norm = btVector3(1.,0.,0.);
        else if ( dy<dx && dy<dz ) norm = btVector3(0.,1.,0.);
//        shape=new btStaticPlaneShape(norm,0);
//        if(!shape){
//            fprintf(stderr,"Error creating btShape\n");
//        }
        //这里要重写shape
        createSun();
        createEarth();
//        osg::ref_ptr<osg::Image> image=osgDB::readImageFile(MOON_IMAGE_PATH);
//        osg::ref_ptr<osg::Texture2D> texture=new osg::Texture2D;
//        texture->setImage(image);
//        texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT); // 在 S 方向重复
//        texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT); // 在 T 方向重复

//        osg::ref_ptr<osg::StateSet> ss=geometryModel->getOrCreateStateSet();
//        ss->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
//        osg::Node* parentNode = geometryModel->getParent(0); // 获取第一个父节点
//        if (parentNode)
//        {
//            osg::Geode* parentGeode = dynamic_cast<osg::Geode*>(geometryModel);
//            if (parentGeode)
//            {
//                unsigned int numChildren = parentGeode->getNumDrawables();
//                std::cout << "Number of siblings (including the geometry node): " << numChildren << std::endl;
//            }
//        }








        osg::Matrix matrix;


        // 提取旋转信息
        osg::Matrix rotationMatrix(matrix);
        rotationMatrix(3, 0) = 0.0;
        rotationMatrix(3, 1) = 0.0;
        rotationMatrix(3, 2) = 0.0;
        osg::Quat rotation;
        rotation.set(rotationMatrix);
//        osg::PositionAttitudeTransform *mat=new osg::PositionAttitudeTransform;
        model->setScale(osg::Vec3(1,1,1));
//        mat->setScale(osg::Vec3(100,100,10));
//        mat->addChild(ground);
        model->setAttitude(rotation);
        osg::Vec3 position(0,0,10);
        model->setPosition(position);












//                if (geometry) {
//                    osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
//                    if (vertices) {
//                        // 调试输出顶点数量
//                        std::cout << "Number of vertices: " << vertices->size() << std::endl;
//                        // 检查每个顶点的数值
//                        for (size_t i = 0; i < vertices->size(); i++) {
//                            const osg::Vec3& vertex = (*vertices)[i];
//                            std::cout << "Vertex " << i << ": " << vertex.x() << ", " << vertex.y() << ", " << vertex.z() << std::endl;
//                        }
//                    } else {
//                        std::cout << "Failed to get vertex array." << std::endl;
//                    }
//                } else {
//                    std::cout << "Failed to get geometry." << std::endl;
//                }



        osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());


        // 创建三角网格
            btTriangleMesh* triangleMesh = new btTriangleMesh();
            for (size_t i = 0; i < vertices->size(); i += 3) {
                osg::Vec3 v1 = (*vertices)[i];
                osg::Vec3 v2 = (*vertices)[i+1];
                osg::Vec3 v3 = (*vertices)[i+2];
                triangleMesh->addTriangle(btVector3(v1.x(), v1.y(), v1.z()),
                                          btVector3(v2.x(), v2.y(), v2.z()),
                                          btVector3(v3.x(), v3.y(), v3.z()));
            }

            // 创建三角网格形状
            btBvhTriangleMeshShape* triangleMeshShape = new btBvhTriangleMeshShape(triangleMesh, true);


           shape=triangleMeshShape;
        btTransform transform;

        // 设置位置

        transform.setOrigin(btVector3(position.x(),position.y(),position.z()));

        // 设置属性（旋转和缩放）
//        btQuaternion rotation(0.0f, 0.0f, 0.0f, 1.0f);  // 旋转四元数


        transform.setRotation(btQuaternion(rotation.x(),rotation.y(),rotation.z(),rotation.w()));





        shape->setMargin(0.0001);

        // 绘制凸包形状

//        osg::Geometry* convexGeometry = new osg::Geometry();
//        osg::Vec3Array* convexVertices = new osg::Vec3Array();

//        for (int i = 0; i < convShape->getNumVertices(); i++)
//        {
//            btVector3 vertex;
//            convShape->getVertex(i, vertex);
//            osg::Vec3 osgVertex(vertex.x(), vertex.y(), vertex.z());
//            convexVertices->push_back(osgVertex);
//        }

//        convexGeometry->setVertexArray(convexVertices);
//        osg::ref_ptr<osg::DrawArrays> drawArrays = new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, convexVertices->size()-2);

//        convexGeometry->addPrimitiveSet(drawArrays);
//        mat->addChild(convexGeometry);
//        geo->addChild(mat);






        btDefaultMotionState* mState = new
            btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0.,0.,0.)));
        btVector3 inertia(0,0,0);
        //shape->calculateLocalInertia(mass,inertia);
        btRigidBody::btRigidBodyConstructionInfo cInfo(mass,mState,triangleMeshShape,inertia);
        cInfo.m_restitution=0.9f;
        cInfo.m_friction=0.9f;

        body=new btRigidBody(cInfo);
        if ( !body ) fprintf(stderr,"Error creating btBody\n");

        this->setRotation(rotation);
//        this->setPosition(position);
//        btTransform *wTrans=new btTransform(rotation,posit);

//        this->setTransform()


        this->setTransform(transform);
        btVector3 scale(1, 1,1);
        body->getCollisionShape()->setLocalScaling(scale);

       /**********************************************************************************************
        // 获取三角网格形状的包围盒
        btVector3 aabbMin, aabbMax;
        triangleMeshShape->getAabb(btTransform::getIdentity(), aabbMin, aabbMax);

        // 计算包围盒的大小
        btVector3 aabbSize = aabbMax - aabbMin;

        // 打印包围盒的大小
        printf("groudn AABB Size: x = %f, y = %f, z = %f\n", aabbSize.x(), aabbSize.y(), aabbSize.z());


         */




//        createRigidBody();

    }



////修改包围盒的
//    btosgMoonGround(float dx, float dy, float dz)  {
//      //  /// Constructs a physical infinite plane, viewable as low thickness finite box.
//      //  /// Viewable box has dimensions dx,dy,dz.
//       // /// Minimum dimension selects physical plane orientation.
//       // /// Plane is created as axis oriented.
//        dx=max(dx,0.001);
//        dy=max(dy,0.001);
//        dz=max(dz,0.001);
////        osg::Geode *geo=new osg::Geode;
////        if(geo){
////            osg::Shape *sp=new osg::Box(osg::Vec3(0.,0.,0.),dx,dy,dz);
////            if(sp){
////                osg::ShapeDrawable *sd=new osg::ShapeDrawable(sp);
////                if(sd){
////                    geo->addDrawable(sd);
////                }else fprintf(stderr,"Error creating osg::Shape\n");
////            } else fprintf(stderr,"Error creating osg::Shape\n");
////        } else fprintf(stderr,"Error creating Geode\n");
//        osg::Geode *geo=new osg::Geode;
//        osg::Node *ground=osgDB::readNodeFile(MYMOONGROUND_PATH);







//        if ( !model )	model = new osg::PositionAttitudeTransform;
//        model->addChild(geo);
//        //这个是什么意思
//        model->setNodeMask(ReceivesShadowTraversalMask);
//        mass = 0;
//        btVector3 norm(0.,0.,1);
//        if ( dx<dy && dx<dz ) 	   norm = btVector3(1.,0.,0.);
//        else if ( dy<dx && dy<dz ) norm = btVector3(0.,1.,0.);
////        shape=new btStaticPlaneShape(norm,0);
////        if(!shape){
////            fprintf(stderr,"Error creating btShape\n");
////        }
//        //这里要重写shape





//        osg::Geometry *geometry=findGeometryNode(ground);
////        osg::Matrix matrix=findGeometryMatrix(ground);
//        osg::Matrix matrix;


//        // 提取旋转信息
//        osg::Matrix rotationMatrix(matrix);
//        rotationMatrix(3, 0) = 0.0;
//        rotationMatrix(3, 1) = 0.0;
//        rotationMatrix(3, 2) = 0.0;
//        osg::Quat rotation;
//        rotation.set(rotationMatrix);
//        osg::PositionAttitudeTransform *mat=new osg::PositionAttitudeTransform;
//        mat->setScale(osg::Vec3(0.1,0.1,0.1));
////        mat->setScale(osg::Vec3(100,100,100));
////        mat->addChild(ground);
//        mat->setAttitude(rotation);
//        osg::Vec3 position(-10, 0,0);
//        mat->setPosition(position);


//        mat->addChild(geometry);
//        geo->addChild(mat);






//                if (geometry) {
//                    osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
//                    if (vertices) {
//                        // 调试输出顶点数量
//                        std::cout << "Number of vertices: " << vertices->size() << std::endl;

//                        // 检查每个顶点的数值
//                        for (size_t i = 0; i < vertices->size(); i++) {
//                            const osg::Vec3& vertex = (*vertices)[i];
//                            std::cout << "Vertex " << i << ": " << vertex.x() << ", " << vertex.y() << ", " << vertex.z() << std::endl;
//                        }
//                    } else {
//                        std::cout << "Failed to get vertex array." << std::endl;
//                    }
//                } else {
//                    std::cout << "Failed to get geometry." << std::endl;
//                }



////        if(geometry){
////            osg::Vec3Array* veticse=dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
////            if(veticse){
////                for(size_t i=0;i<veticse->size();i++){
////                    const osg::Vec3 &vertex=(*veticse)[i]*100;
////                    convShape->addPoint(btVector3(vertex.x(),vertex.y(),vertex.z()));


////                }
////            }
////       }



//// * 凸包
//          btConvexHullShape *convShape=new btConvexHullShape;


//        if (geometry) {
//            osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
//            if (vertices) {
//                size_t i = 0;

////
//                for (; i < vertices->size(); i++) {
//                    const osg::Vec3& vertex = (*vertices)[i];
//                    convShape->addPoint(btVector3(vertex.x()*0.1, vertex.y()*0.1, vertex.z()*0.1));
//                }

////
//            } else {
//                fprintf(stderr, "Failed to get vertex array.\n");
//            }
//        } else {
//            fprintf(stderr, "Failed to get geometry.\n");
//        }


//        shape=convShape;


//        btTransform transform;

//        // 设置位置

//        transform.setOrigin(btVector3(position.x(),position.y(),position.z()));

//        // 设置属性（旋转和缩放）
////        btQuaternion rotation(0.0f, 0.0f, 0.0f, 1.0f);  // 旋转四元数


//        transform.setRotation(btQuaternion(rotation.x(),rotation.y(),rotation.z(),rotation.w()));



////        shape=convShape;




//        shape->setMargin(0.0000001);






//        // 绘制凸包形状

////        osg::Geometry* convexGeometry = new osg::Geometry();
////        osg::Vec3Array* convexVertices = new osg::Vec3Array();

////        for (int i = 0; i < convShape->getNumVertices(); i++)
////        {
////            btVector3 vertex;
////            convShape->getVertex(i, vertex);
////            osg::Vec3 osgVertex(vertex.x(), vertex.y(), vertex.z());
////            convexVertices->push_back(osgVertex);
////        }

////        convexGeometry->setVertexArray(convexVertices);
////        osg::ref_ptr<osg::DrawArrays> drawArrays = new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, convexVertices->size()-2);

////        convexGeometry->addPrimitiveSet(drawArrays);
////        mat->addChild(convexGeometry);
////        geo->addChild(mat);






//        btDefaultMotionState* mState = new
//            btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0.,0.,0.)));
//        btVector3 inertia(0,0,0);
//        //shape->calculateLocalInertia(mass,inertia);
//        btRigidBody::btRigidBodyConstructionInfo cInfo(mass,mState,convShape,inertia);
//        cInfo.m_restitution=0.9f;
//        cInfo.m_friction=0.9f;

//        body=new btRigidBody(cInfo);
//        if ( !body ) fprintf(stderr,"Error creating btBody\n");

//        this->setRotation(rotation);
////        this->setPosition(position);
////        btTransform *wTrans=new btTransform(rotation,posit);

////        this->setTransform()


//        this->setTransform(transform);

////        btVector3 scale(0.1, 0.1,0.1);
////        body->getCollisionShape()->setLocalScaling(scale);




////        AABB Min: -183.73, -173.37, -13.45
////        AABB Max: 163.43, 173.57, 11.40




////        createRigidBody();

//        btVector3 aabbMin, aabbMax;
//        convShape->setLocalScaling(btVector3(1, 1, 1)); // 重置缩放
//        convShape->optimizeConvexHull();
//         convShape->getAabb(btTransform::getIdentity(), aabbMin, aabbMax);
//        // 获取修改后的包围盒
//        printf("Modified AABB Min: %.2f, %.2f, %.2f\n", aabbMin.x(), aabbMin.y(), aabbMin.z());
//           printf("Modified AABB Max: %.2f, %.2f, %.2f\n", aabbMax.x(), aabbMax.y(), aabbMax.z());


//        // 打印包围盒的最小和最大点
//        btVector3 newLocalAabbCenter = (aabbMin + aabbMax) * 0.5f;
//            btVector3 newLocalAabbHalfExtents = (aabbMax -  aabbMin) * 0.5f;
//            newLocalAabbCenter.setZ(newLocalAabbCenter.z() - 20.0f);
//            convShape->setImplicitShapeDimensions(newLocalAabbCenter);
//            convShape->setLocalScaling(btVector3(1, 1, 0.5));

//            convShape->recalcLocalAabb();


//         convShape->getAabb(btTransform::getIdentity(), aabbMin, aabbMax);
//         printf("Modified AABB Min: %.2f, %.2f, %.2f\n", aabbMin.x(), aabbMin.y(), aabbMin.z());
//            printf("Modified AABB Max: %.2f, %.2f, %.2f\n", aabbMax.x(), aabbMax.y(), aabbMax.z());

//    }






    ////100个凸包
    //    btosgMoonGround(float dx, float dy, float dz)  {
    //      //  /// Constructs a physical infinite plane, viewable as low thickness finite box.
    //      //  /// Viewable box has dimensions dx,dy,dz.
    //       // /// Minimum dimension selects physical plane orientation.
    //       // /// Plane is created as axis oriented.
    //        dx=max(dx,0.001);
    //        dy=max(dy,0.001);
    //        dz=max(dz,0.001);
    ////        osg::Geode *geo=new osg::Geode;
    ////        if(geo){
    ////            osg::Shape *sp=new osg::Box(osg::Vec3(0.,0.,0.),dx,dy,dz);
    ////            if(sp){
    ////                osg::ShapeDrawable *sd=new osg::ShapeDrawable(sp);
    ////                if(sd){
    ////                    geo->addDrawable(sd);
    ////                }else fprintf(stderr,"Error creating osg::Shape\n");
    ////            } else fprintf(stderr,"Error creating osg::Shape\n");
    ////        } else fprintf(stderr,"Error creating Geode\n");
    //        osg::Geode *geo=new osg::Geode;
    //        osg::Node *ground=osgDB::readNodeFile(MYMOONGROUND_PATH);







    //        if ( !model )	model = new osg::PositionAttitudeTransform;
    //        model->addChild(geo);
    //        //这个是什么意思
    //        model->setNodeMask(ReceivesShadowTraversalMask);
    //        mass = 0;
    //        btVector3 norm(0.,0.,1);
    //        if ( dx<dy && dx<dz ) 	   norm = btVector3(1.,0.,0.);
    //        else if ( dy<dx && dy<dz ) norm = btVector3(0.,1.,0.);
    ////        shape=new btStaticPlaneShape(norm,0);
    ////        if(!shape){
    ////            fprintf(stderr,"Error creating btShape\n");
    ////        }
    //        //这里要重写shape





    //        osg::Geometry *geometry=findGeometryNode(ground);
    //        osg::ref_ptr<osg::DrawElementsUShort> indices = dynamic_cast<osg::DrawElementsUShort*>(geometry->getPrimitiveSet(0));
    //        if (geometry) {
    //               osg::ref_ptr<osg::PrimitiveSet> primitiveSet = geometry->getPrimitiveSet(0);


    //               if (primitiveSet.valid()) {
    //                          osg::PrimitiveSet::Type primitiveType = primitiveSet->getType();
    //                          const char* typeName = primitiveSet->className();
    //                          std::cout << "PrimitiveSet type: " << typeName << std::endl;
    //                          qDebug()<<"PrimitiveSet type: "<<QString(typeName) ;
    //                          qDebug()<<QString(primitiveSet.get()->getMode()) ;

    //                }

    //           }
    ////        osg::Matrix matrix=findGeometryMatrix(ground);
    //        osg::Matrix matrix;


    //        // 提取旋转信息
    //        osg::Matrix rotationMatrix(matrix);
    //        rotationMatrix(3, 0) = 0.0;
    //        rotationMatrix(3, 1) = 0.0;
    //        rotationMatrix(3, 2) = 0.0;
    //        osg::Quat rotation;
    //        rotation.set(rotationMatrix);

    //        model->setScale(osg::Vec3(0.1,0.1,0.1));
    ////        mat->setScale(osg::Vec3(100,100,100));
    ////        mat->addChild(ground);
    //        model->setAttitude(rotation);
    //        osg::Vec3 position(0, 0,0);
    //        model->setPosition(position);

    //        geo->addChild(geometry);







    //                if (geometry) {
    //                    osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
    //                    if (vertices) {
    //                        // 调试输出顶点数量
    //                        std::cout << "Number of vertices: " << vertices->size() << std::endl;

    //                        // 检查每个顶点的数值
    //                        for (size_t i = 0; i < vertices->size(); i++) {
    //                            const osg::Vec3& vertex = (*vertices)[i]*0.1;
    //                            std::cout << "Vertex " << i << ": " << vertex.x() << ", " << vertex.y() << ", " << vertex.z() << std::endl;
    //                        }
    //                    } else {
    //                        std::cout << "Failed to get vertex array." << std::endl;
    //                    }
    //                } else {
    //                    std::cout << "Failed to get geometry." << std::endl;
    //                }






    //// *100 凸包
    ////                int n=1;

    ////         btConvexHullShape **convShape=new btConvexHullShape*[n];
    ////          for (size_t i = 0; i < n; i++) {
    ////              convShape[i] = new btConvexHullShape();
    ////          }
    ////         btCompoundShape* compound = new btCompoundShape();
    ////        if (geometry) {
    ////            osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
    ////            if (vertices) {
    ////                size_t i = 0;
    ////                int vlen=vertices->size()/n;

    ////                for (; i < n; i++) {
    ////                    for(int j=vlen*i;j<vlen*(i+1)&&vertices->size();j++){
    ////                        const osg::Vec3& vertex = (*vertices)[j];
    ////                        convShape[i]->addPoint(btVector3(vertex.x()*0.1, vertex.y()*0.1, vertex.z()*0.1));
    ////                    }
    ////                    convShape[i]->optimizeConvexHull();
    ////                    compound->addChildShape(btTransform::getIdentity(),convShape[i]);
    ////                }

    //////
    ////            } else {
    ////                fprintf(stderr, "Failed to get vertex array.\n");
    ////            }
    ////        } else {
    ////            fprintf(stderr, "Failed to get geometry.\n");
    ////        }

    //        btConvexHullShape *convShape=new btConvexHullShape();
    //        if (geometry) {
    //            osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
    //            if (vertices) {

    //                for (size_t i = 0; i <vertices->size(); i++){
    //                    const osg::Vec3& vertex = (*vertices)[i];
    //                    convShape->addPoint(btVector3(vertex.x()*0.1, vertex.y()*0.1, vertex.z()*0.1));
    //                }


    ////
    //            } else {
    //                fprintf(stderr, "Failed to get vertex array.\n");
    //            }
    //        } else {
    //            fprintf(stderr, "Failed to get geometry.\n");
    //        }
    //        convShape->optimizeConvexHull();
    //        shape=convShape;

    //        btTransform transform;

    //        // 设置位置

    //        transform.setOrigin(btVector3(position.x(),position.y(),position.z()));

    //        // 设置属性（旋转和缩放）
    ////        btQuaternion rotation(0.0f, 0.0f, 0.0f, 1.0f);  // 旋转四元数


    //        transform.setRotation(btQuaternion(rotation.x(),rotation.y(),rotation.z(),rotation.w()));



    ////        shape=convShape;

    //        btVector3 aabbMin, aabbMax;
    //            shape->getAabb(btTransform::getIdentity(), aabbMin, aabbMax);

    //            // 打印包围盒的最小和最大点
    //            printf("AABB Min: %.2f, %.2f, %.2f\n", aabbMin.x(), aabbMin.y(), aabbMin.z());
    //            printf("AABB Max: %.2f, %.2f, %.2f\n", aabbMax.x(), aabbMax.y(), aabbMax.z());


    //        shape->setMargin(0.0000001);
    //        // 更新包围盒

    //        convShape->recalcLocalAabb();

    //        // 获取修改后的包围盒
    //        shape->getAabb(btTransform::getIdentity(), aabbMin, aabbMax);
    //        // 打印包围盒的最小和最大点


    //        // 绘制凸包形状

    ////        osg::Geometry* convexGeometry = new osg::Geometry();
    ////        osg::Vec3Array* convexVertices = new osg::Vec3Array();

    ////        for (int i = 0; i < convShape->getNumVertices(); i++)
    ////        {
    ////            btVector3 vertex;
    ////            convShape->getVertex(i, vertex);
    ////            osg::Vec3 osgVertex(vertex.x(), vertex.y(), vertex.z());
    ////            convexVertices->push_back(osgVertex);
    ////        }

    ////        convexGeometry->setVertexArray(convexVertices);
    ////        osg::ref_ptr<osg::DrawArrays> drawArrays = new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, convexVertices->size()-2);

    ////        convexGeometry->addPrimitiveSet(drawArrays);
    ////        mat->addChild(convexGeometry);
    ////        geo->addChild(mat);






    //        btDefaultMotionState* mState = new
    //            btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0.,0.,0.)));
    //        btVector3 inertia(0,0,0);
    //        //shape->calculateLocalInertia(mass,inertia);
    //        btRigidBody::btRigidBodyConstructionInfo cInfo(mass,mState,shape,inertia);
    //        cInfo.m_restitution=0.9f;
    //        cInfo.m_friction=0.9f;

    //        body=new btRigidBody(cInfo);
    //        if ( !body ) fprintf(stderr,"Error creating btBody\n");

    //        this->setRotation(rotation);
    ////        this->setPosition(position);
    ////        btTransform *wTrans=new btTransform(rotation,posit);

    ////        this->setTransform()


    //        this->setTransform(transform);
    ////        btVector3 scale(0.1, 0.1,0.1);
    ////        body->getCollisionShape()->setLocalScaling(scale);




    ////        AABB Min: -183.73, -173.37, -13.45
    ////        AABB Max: 163.43, 173.57, 11.40




    ////        createRigidBody();

    //    }




////用高度地面是试一试
//    btosgMoonGround(float dx, float dy, float dz)  {
//      //  /// Constructs a physical infinite plane, viewable as low thickness finite box.
//      //  /// Viewable box has dimensions dx,dy,dz.
//       // /// Minimum dimension selects physical plane orientation.
//       // /// Plane is created as axis oriented.
//        dx=max(dx,0.001);
//        dy=max(dy,0.001);
//        dz=max(dz,0.001);
////        osg::Geode *geo=new osg::Geode;
////        if(geo){
////            osg::Shape *sp=new osg::Box(osg::Vec3(0.,0.,0.),dx,dy,dz);
////            if(sp){
////                osg::ShapeDrawable *sd=new osg::ShapeDrawable(sp);
////                if(sd){
////                    geo->addDrawable(sd);
////                }else fprintf(stderr,"Error creating osg::Shape\n");
////            } else fprintf(stderr,"Error creating osg::Shape\n");
////        } else fprintf(stderr,"Error creating Geode\n");
//        osg::Geode *geo=new osg::Geode;
//        osg::Node *ground=osgDB::readNodeFile(MYMOONGROUND_PATH);



//        if ( !model )	model = new osg::PositionAttitudeTransform;
//        model->addChild(geo);
//        //这个是什么意思
//        model->setNodeMask(ReceivesShadowTraversalMask);
//        mass = 0;
//        btVector3 norm(0.,0.,1);
//        if ( dx<dy && dx<dz ) 	   norm = btVector3(1.,0.,0.);
//        else if ( dy<dx && dy<dz ) norm = btVector3(0.,1.,0.);
////        shape=new btStaticPlaneShape(norm,0);
////        if(!shape){
////            fprintf(stderr,"Error creating btShape\n");
////        }
//        //这里要重写shape





//        osg::Geometry *geometry=findGeometryNode(ground);

//        if (geometry) {
//               osg::ref_ptr<osg::PrimitiveSet> primitiveSet = geometry->getPrimitiveSet(0);


//               if (primitiveSet.valid()) {
//                          osg::PrimitiveSet::Type primitiveType = primitiveSet->getType();
//                          const char* typeName = primitiveSet->className();
//                          std::cout << "PrimitiveSet type: " << typeName << std::endl;
//                          qDebug()<<"PrimitiveSet type: "<<QString(typeName) ;


//                }
//           }






//        osg::Matrix matrix;


//        // 提取旋转信息
//        osg::Matrix rotationMatrix(matrix);
//        rotationMatrix(3, 0) = 0.0;
//        rotationMatrix(3, 1) = 0.0;
//        rotationMatrix(3, 2) = 0.0;
//        osg::Quat rotation;
//        rotation.set(rotationMatrix);
//        osg::PositionAttitudeTransform *mat=new osg::PositionAttitudeTransform;
//        mat->setScale(osg::Vec3(0.1,0.1,0.1));
////        mat->setScale(osg::Vec3(100,100,100));
////        mat->addChild(ground);
//        mat->setAttitude(rotation);
//        osg::Vec3 position(-10, -10,-10);
//        mat->setPosition(position);


//        mat->addChild(geometry);
//        geo->addChild(mat);






//                if (geometry) {
//                    osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());


//                    int numPoints = vertices->size(); // 几何点的数量

//                    // 找到最小和最大的点坐标值，以确定地形的范围
//                    float minX = (*vertices)[0].x()*0.1;
//                    float maxX = (*vertices)[0].x()*0.1;
//                    float minY =(*vertices)[0].y()*0.1;
//                    float maxY = (*vertices)[0].y()*0.1;
//                    for (int i = 1; i < numPoints; ++i) {
//                        if ((*vertices)[i].x()*0.1 < minX) minX = (*vertices)[i].x()*0.1;
//                        if ((*vertices)[i].x()*0.1 > maxX) maxX = (*vertices)[i].x()*0.1;
//                        if ((*vertices)[i].y()*0.1 < minY) minY = (*vertices)[i].y()*0.1;
//                        if ((*vertices)[i].y()*0.1 > maxY) maxY = (*vertices)[i].y()*0.1;
//                    }

//                    int width = maxX - minX; // 地形的宽度，根据需要进行调整
//                    int length = maxY - minY; // 地形的长度，根据需要进行调整
//                    float* heightData = new float[width * length];

//                    // 将几何点的高度值映射到高度数据数组中
//                    for (int i = 0; i < numPoints; ++i) {
//                        float x = (*vertices)[i].x()*0.1;
//                        float y = (*vertices)[i].y()*0.1;
//                        float height = (*vertices)[i].z()*0.1;

//                        // 计算点在高度数据数组中的索引
//                        int row = static_cast<int>((x - minX) / (maxX - minX) * (width - 1));
//                        int col = static_cast<int>((y - minY) / (maxY - minY) * (length - 1));
////                         printf("%d\n",i);
////                         printf("row=%d\n",row);
////                         printf("col=%d\n",col);
//                        qDebug()<<"i="<<i<<",row="<<row<<",col="<<col<<",width * length="<<width * length<<",size="<<numPoints;
//                        // 设置对应索引处的高度值
//                        heightData[row * width + col] = height;

//                    }
//                    for(int i=1;i<width*length;i++){
//                        heightData[i]=heightData[i-1];
//                    }
//                    btHeightfieldTerrainShape* terrainShape = new btHeightfieldTerrainShape(
//                        width, length, heightData, 1.0f, -1.0f, 1.0f, 1, PHY_FLOAT, false
//                    );
//                    shape=terrainShape;



//                    if (vertices) {
//                        // 调试输出顶点数量
//                        std::cout << "Number of vertices: " << vertices->size() << std::endl;

//                        // 检查每个顶点的数值
//                        for (size_t i = 0; i < vertices->size(); i++) {
//                            const osg::Vec3& vertex = (*vertices)[i];
//                            std::cout << "Vertex " << i << ": " << vertex.x() << ", " << vertex.y() << ", " << vertex.z() << std::endl;
//                        }
//                    } else {
//                        std::cout << "Failed to get vertex array." << std::endl;
//                    }
//                } else {
//                    std::cout << "Failed to get geometry." << std::endl;
//                }



////        if(geometry){
////            osg::Vec3Array* veticse=dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
////            if(veticse){
////                for(size_t i=0;i<veticse->size();i++){
////                    const osg::Vec3 &vertex=(*veticse)[i]*100;
////                    convShape->addPoint(btVector3(vertex.x(),vertex.y(),vertex.z()));


////                }
////            }
////       }



//// * 凸包
//                int n=1;



//        btTransform transform;

//        // 设置位置

//        transform.setOrigin(btVector3(position.x(),position.y(),position.z()));

//        // 设置属性（旋转和缩放）
////        btQuaternion rotation(0.0f, 0.0f, 0.0f, 1.0f);  // 旋转四元数


//        transform.setRotation(btQuaternion(rotation.x(),rotation.y(),rotation.z(),rotation.w()));




//        btVector3 aabbMin, aabbMax;
//            shape->getAabb(btTransform::getIdentity(), aabbMin, aabbMax);

//            // 打印包围盒的最小和最大点
//            printf("AABB Min: %.2f, %.2f, %.2f\n", aabbMin.x(), aabbMin.y(), aabbMin.z());
//            printf("AABB Max: %.2f, %.2f, %.2f\n", aabbMax.x(), aabbMax.y(), aabbMax.z());


//        shape->setMargin(0.0000001);
//        // 更新包围盒



//        // 获取修改后的包围盒
//        shape->getAabb(btTransform::getIdentity(), aabbMin, aabbMax);
//        // 打印包围盒的最小和最大点


//        // 绘制凸包形状

////        osg::Geometry* convexGeometry = new osg::Geometry();
////        osg::Vec3Array* convexVertices = new osg::Vec3Array();

////        for (int i = 0; i < convShape->getNumVertices(); i++)
////        {
////            btVector3 vertex;
////            convShape->getVertex(i, vertex);
////            osg::Vec3 osgVertex(vertex.x(), vertex.y(), vertex.z());
////            convexVertices->push_back(osgVertex);
////        }

////        convexGeometry->setVertexArray(convexVertices);
////        osg::ref_ptr<osg::DrawArrays> drawArrays = new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, convexVertices->size()-2);

////        convexGeometry->addPrimitiveSet(drawArrays);
////        mat->addChild(convexGeometry);
////        geo->addChild(mat);






//        btDefaultMotionState* mState = new
//            btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0.,0.,0.)));
//        btVector3 inertia(0,0,0);
//        //shape->calculateLocalInertia(mass,inertia);

//        btRigidBody::btRigidBodyConstructionInfo cInfo(mass,mState,shape,inertia);
//        cInfo.m_restitution=0.9f;
//        cInfo.m_friction=0.9f;

//        body=new btRigidBody(cInfo);
//        if ( !body ) fprintf(stderr,"Error creating btBody\n");

//        this->setRotation(rotation);
////        this->setPosition(position);
////        btTransform *wTrans=new btTransform(rotation,posit);

////        this->setTransform()


//        this->setTransform(transform);
////        btVector3 scale(0.1, 0.1,0.1);
////        body->getCollisionShape()->setLocalScaling(scale);




////        AABB Min: -183.73, -173.37, -13.45
////        AABB Max: 163.43, 173.57, 11.40




////        createRigidBody();

//    }

    void createRigidBody() {

         /// Creates a Rigid Body
        btDefaultMotionState* mState = new
            btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0.,0.,0.)));
        btVector3 inertia(0,0,0);
        //shape->calculateLocalInertia(mass,inertia);
        btRigidBody::btRigidBodyConstructionInfo cInfo(mass,mState,shape,inertia);
        cInfo.m_restitution=0.9f;
        cInfo.m_friction=0.9f;
        body=new btRigidBody(cInfo);
        if ( !body ) fprintf(stderr,"Error creating btBody\n");
//        btVector3 scale(0.05, 0.05, 0.05);
//        btVector3 scale(100, 100, 100);
//        body->getCollisionShape()->setLocalScaling(scale);

    }
    ~btosgMoonGround() {

    }
    osg::Geometry* findGeometryNode(osg::Node* node) {
        if(node){
            if (node->asGeode()) {
                osg::Geode* geode = node->asGeode();
                for (unsigned int i = 0; i < geode->getNumDrawables(); ++i) {
                    osg::Geometry* geometry = geode->getDrawable(i)->asGeometry();
                    if (geometry) {
                        return geometry;
                    }
                }
            }

            osg::Group* group = node->asGroup();
            if (group) {
                for (unsigned int i = 0; i < group->getNumChildren(); ++i) {
                    osg::Geometry* geometry = findGeometryNode(group->getChild(i));
                    if (geometry) {
                        return geometry;
                    }
                }
            }
        }


        return nullptr;
    }




    osg::Matrix getGeometryMatrix(osg::Geometry* geometry)
    {
        osg::Node* parentNode = geometry->getParent(0);
        if (parentNode)
        {
            osg::MatrixTransform* transformNode = dynamic_cast<osg::MatrixTransform*>(parentNode);
            if (transformNode)
            {
                return transformNode->getMatrix();
            }
        }

        return osg::Matrix::identity();
    }

    osg::Matrix findGeometryMatrix(osg::Node* node)
    {
        if (node)
        {
            if (node->asGeode())
            {
                osg::Geode* geode = node->asGeode();
                for (unsigned int i = 0; i < geode->getNumDrawables(); ++i)
                {
                    osg::Geometry* geometry = geode->getDrawable(i)->asGeometry();
                    if (geometry)
                    {
                        return getGeometryMatrix(geometry);
                    }
                }
            }

            osg::Group* group = node->asGroup();
            if (group)
            {
                for (unsigned int i = 0; i < group->getNumChildren(); ++i)
                {
                    osg::Matrix matrix = findGeometryMatrix(group->getChild(i));
                    if (!matrix.isIdentity())
                    {
                        return matrix;
                    }
                }
            }
        }

        return osg::Matrix::identity();
    }





};








#endif // BTOSG_H
